package handlers

import (
	"class08/config"
	"class08/model"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v4"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
	"net/http"
)

type Handlers struct {
	DB *gorm.DB
}

// 用户注册
func (h *Handlers) SignUp(c *gin.Context) {
	var user model.User
	//解析数据
	if err := c.BindJSON(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"error": err.Error(),
		})
		return

	}
	//	判断用户名是否存在
	var existingUer model.User
	h.DB.Where("username = ?", user.Username).First(&existingUer)
	//不等于0表中有记录
	if existingUer.ID != 0 {
		c.JSON(http.StatusConflict, gin.H{"error": "username is already"})
		return
	}
	//hash加密
	hashpassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	//将加密后的密码给user
	user.Password = string(hashpassword)
	h.DB.Create(&user)
	c.JSON(http.StatusCreated, user)

}

// 用户登录过程
func (h *Handlers) SignIn(c *gin.Context) {
	var user model.User

	//把上下文传来的登录信息，赋值给user
	if err := c.BindJSON(&user); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	//用户名是否存在
	var existingUser model.User
	//根据名称查询结果赋值给existingUser
	h.DB.Where("username = ?", user.Username).First(&existingUser)

	if existingUser.ID == 0 {
		c.JSON(http.StatusUnauthorized, gin.H{"error": "username or password is wrong"})
	}

	//进行密码比较
	err := bcrypt.CompareHashAndPassword([]byte(existingUser.Password), []byte(user.Password))
	if err != nil {
		//比对出错
		c.JSON(http.StatusUnauthorized, gin.H{"Invalid": "Invalid username or password"})
	}
	//密码比对没有问题是生成token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"id":       existingUser.ID,
		"username": existingUser.Username,
	})

	config.Init()
	//加密token
	signingToken, err := token.SignedString([]byte(config.Cfg.SecretKey))
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"token": signingToken})
}
